import { Component , ViewChild , ElementRef, state} from '@angular/core';
import { NavController , ActionSheetController , ToastController } from 'ionic-angular';
import { BluetoothSerial } from '@ionic-native/bluetooth-serial';
import * as Rx from 'rxjs';
import Aplayer from "Aplayer";
import detect from 'bpm-detective';
import { File } from '@ionic-native/file';
import { DeviceMotion, DeviceMotionAccelerationData } from '@ionic-native/device-motion';
import { HttpClient } from '@angular/common/http';
declare var MediaRetrieve : any;
declare var window : any;
@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  @ViewChild('aplayer') aplyaer : ElementRef;
  //当前运动状态
  public currentStatus : {speed : number , heart : number , mileage : number} = {speed : 10 , heart : 140 , mileage : 1100  };
  //今日运动数据
  public todayRunData : { mileage : number , speed : number , runstatus : string } = { mileage : 1.2 , speed : 3.2 , runstatus : '适中' };
  //今日健康
  public healthy : { heart : number , temperature : number } = { heart : 68 , temperature : 36.5 };


  public runData : { body_temp : number , heart_rate : number , move_speed : string , status : string } = { body_temp : 0 , heart_rate : 0 , status : '暂无' , move_speed : '0' };
  public miles : number = 0;
  
  public bpm = 160;
  private currentBpm : number;

  public newbpm : any = 'N/A';

  //aplayer
  public Ap : any; 

  public songs : any[] = [];


  constructor(
    public navCtrl: NavController,
    private blueTooth : BluetoothSerial,
    private actionSheet : ActionSheetController,
    private toast : ToastController,
    private file : File,
    private http : HttpClient
  ) {

  }

  ngOnInit(){
    this.Ap = new Aplayer({
      container : this.aplyaer.nativeElement,
      audio : [],
      listFolded : true
    });

    this.getData();

    let currentMile = Rx.Observable.timer(1000,1000).subscribe(()=>{
      if(this.currentStatus.mileage > 10*240){
        currentMile.unsubscribe();
        return;
      }
      this.currentStatus.mileage = this.currentStatus.speed + this.currentStatus.mileage;
    });
    try{
      MediaRetrieve.getAudioList(async function(songs){
        for(let song of songs['data']){
          if(song.name.substring(song.name.lastIndexOf(".")+1,song.name.length) == 'mp3' || song.name.substring(song.name.lastIndexOf(".")+1,song.name.length) == 'm4a' ){
            let bpm = await this.Bpm('file://'+song.path);   
            this.songs.push({
              name : song.name,
              url : 'file://'+song.path,
              bpm : bpm
            });
            this.Ap.list.add([
            {
              name : song.name,
              url : 'file://'+song.path,
              bpm : bpm
            }
            ]);
          }
        };
      }.bind(this),function(err){
        console.info('errs',err);
        this.emitTost('未扫描到音乐');
      }.bind(this));
    }catch(err){
      console.error('error',err);
    }
  }

  public musicSwitch : boolean = false;

  ngAfterViewInit(){
    this.Ap.on('play',function(){
      if(this.Ap.list.length == 0){
        this.emitTost('正在扫描歌曲请稍等');
        return;
      }
      console.info(this.Ap);
      console.info('当前播放列表',this.Ap.list);
      this.musicSwitch = true;
      this.getStatus();
    }.bind(this));
    this.Ap.on('pause',function(){
      this.musicSwitch = false;
    }.bind(this));

    //heart
    // setInterval(()=>{
    //   let temperature = Math.ceil(Math.random()*100);
    //   let heart = Math.ceil(Math.random()*100);
    //   let speed = Math.ceil(Math.random() * 10);
    //   this.healthy.heart = (heart > 90 ? 90 : (temperature < 60 ? 60 + Math.ceil(Math.random()*10) : temperature));
    //   this.healthy.temperature = (temperature > 37.5 ? 37.5 - Math.ceil(Math.random()) : (temperature < 36 ? 36 + Math.ceil(Math.random()) : temperature));
    //   let status = ['丰沛满血','放松整理','稳速持续','疲劳'];
    //   this.todayRunData.runstatus = status[Math.floor(Math.random() * status.length + 1)-1];
    //   this.todayRunData.mileage = this.todayRunData.mileage + this.todayRunData.speed;
    // },1000);
    // setInterval(()=>{
    //   let speed = Math.ceil(Math.random() * 10);
    //   this.todayRunData.speed = speed;
    // },6000);
    this.Ap.on('playing',function(){
      let name = decodeURI(this.Ap.audio.currentSrc);
      let index = name.lastIndexOf("\/");  
      name = name.substring(index + 1, name.length);
      for(let k in this.songs){
        if(this.songs[k]['name'] == name){
          console.info('当前song',this.songs[k]);
          console.info('当前song的名字',this.songs[k]['name']);
          console.info('当前song的bpm',this.songs[k]['bpm']);
          const bpm = this.songs[k]['bpm'];
          console.info('playing',bpm);
          this.newbpm = bpm;;
          return;
        }
      }
      this.musicSwitch = true;
    }.bind(this));


    Rx.Observable.timer(3000,3000).subscribe(()=>{
      console.info('laoo');
      if(this.musicSwitch){
        let index = this.closest(this.Ap.list.audios,this.runData.heart_rate);
        let src = decodeURI(this.Ap.audio.currentSrc);
        let srcIndex = src.lastIndexOf("\/");
        let name = src.substring(srcIndex + 1, src.length);
        if(name != this.Ap.list.audios[index]['name']){
          this.Ap.list.switch(index);
        }
        // if(this.todayRunData.speed > 7){
        //   for(let k in this.Ap.list.audios){
        //     if(this.Ap.list.audios[k]['bpm'] > 160){
        //       this.Ap.list.switch(k);
        //       return;
        //     }
        //   }
        // }
      }
     });

  }

  //取相似值
  private closest(arr, num){
    let index = 0;
    let ret = arr[0]['bpm'];
    let distance = Math.abs(ret - num);
    for(let i = 1; i < arr.length; i++){
        let newDistance = Math.abs(arr[i]['bpm'] - num);
        if(newDistance < distance){
            distance = newDistance;
            ret = arr[i];
            index = i;
        }
    }
    return index;
  }

  public getStatus(){
    console.info('songs',this.songs);
   this.newbpm = this.songs[0]['bpm'];
  }


  private emitTost (message){
    let toast = this.toast.create({
        message : message,
        duration : 2000,
        position : 'top'
    });
    toast.present();
  }

  //获取bpm
  private async Bpm(url:string){
    console.info('window对象',window);
    const AudioContext = window.AudioContext || window.webkitAudioContext;
    (window as any).AudioContext = (window as any).AudioContext || (window as any).webkitAudioContext;
    // console.info(window.document.getElementsByTagName('body'));
    let context = new AudioContext();
    try{
      const entry = await this.file.resolveLocalFilesystemUrl(url);
      console.info(entry.fullPath.slice(1));
      const buffer = await this.file.readAsArrayBuffer(entry.filesystem.root.nativeURL,entry.fullPath.slice(1));
      const audiobuffer = await this.decodeAudio(context,buffer);
      context.close();
      const bpm = detect(audiobuffer);
      console.info('bpm is '+bpm);
      this.bpm = bpm;
      return bpm;
    }catch(err){
      console.error('bpmerr:',err);
    }
  }
  //decode 解码新旧版本
  private async decodeAudio(context , buffer){
    try{
      const audioBuffer = await context.decodeAudioData(buffer);
      return audioBuffer;
    }catch(err){
      console.info('decode error',err);
      return new Promise((resolve,reject)=>{
        context.decodeAudioData(buffer,(decodeData)=>{
          resolve(decodeData);
        });
      });
    }
  }


  // =======================================================全新的类  音乐异步监听流程============================================================///
  //跑步速度
  private runSpeed : number = 0;
  //心率
  private heartBpm : number = 0;
  //推荐bpm
  private recommendBpm : number = 0;
  //歌曲列表bpm组
  private bpms = this.songs;
  //当前bpm
  private activeBpm : number = 0  

  //bpm监听器


  private getData(){
    const intvel = Rx.Observable.timer(1000,1000);
    intvel.concatMap(ev=>this.http.get('http://www.akatosh.cn/rundata').catch((err,caught)=>{
      return caught;
    })).subscribe((response)=>{
      const res : rundataRes = response['content'];
      this.runData = { body_temp : res.body_temp , heart_rate : res.heart_rate , status : res.status , move_speed : res.move_speed };
      this.miles = parseInt(res.move_speed) + this.miles;
    },err=>{
      console.error('error',err);
    });
  }

}

export interface rundataRes{
  body_temp : number,
  heart_rate : number,
  status : string,
  move_speed : string,
  create_time : string  
}


/**
 * 项目技术
 * 1 UI 使用html5 + css + ionicUI
 * 2 app逻辑 使用 angular5 + cordova封装插件
 * 3 所需开发环境 nodejs + npm
 * 4 打包技术 webpack + aot编译
 * 
 * html5 css3 typescript 
 * 
 * 
 * 节拍提取
 * audiobuffer 转换成bpm
 * audiobuffer 通过赋值给audiocontext上下文 
 * 然后把audiobuffersourcenode 和 audiocontext相连
 * audioContext有个analyser分析器
 * 循环audiobuffersourcenode然后通过analyser 获取能量值
 * 然后剩下的我就是以3s为区间获取峰值 峰值获取完再通过冒泡比较把非峰值去掉
 * 剩下的峰值除以时间就是bpm
 * 
 */